﻿#ifndef COMMON_H
#define COMMON_H
#include <iostream>
#include <string>
#include <chrono>
#include <deque>
#include <map>
#include <sstream>
#include <QDebug>
#include <QDir>
#include <QTextCodec>
#include <QSettings>
#include <fstream>
#include <QThread>
#include <thread>
#include <mutex>
#include <regex>
#include <QMessageBox>
#include <QNetworkAccessManager>
#include <QtNetwork>
#include "log.h"
#include "DlgCustom.h"
#include <sys/stat.h>

using namespace std;

#ifdef WIN32  
#pragma execution_character_set("utf-8")  
#endif

#ifndef MAX_PATH
#define MAX_PATH 260
#endif

#define WEB_ADDRESS_HEAD_FIND_LENGTH 8
#define WEB_FIND_CHARSET_MAX_LEN 800
//MB搜索算法用
#define BM_SEARCH_TABLE_LENGTH 256
//一章的最大长度
#define CHAPTER_MAX_LEN 40000
//网书图片文件名
#define WEB_BOOK_IMAGE_FILE_NAME "/image.jpg"
#define BUTTON_IN_PROGRESS "中..."
///等待子线程退出最大时间(ms)
#define WAIT_THREAD_EXIT_TIME 20000

//书信息保存目录
#ifdef __ANDROID__
#include <QtAndroid>
#include <QAndroidJniEnvironment>
#include <QAndroidJniObject>
#define ROOT_PATH "/storage/emulated/0/"
#define BOOK_LIST_SAVE_DIR ROOT_PATH"FreeReader/BooksInfo/"


bool requestPermission();

#else
#include <io.h>
#define ROOT_PATH "/"
#define BOOK_LIST_SAVE_DIR ROOT_PATH"FreeReader/BooksInfo/"
#endif

//文字默认字体点大小
#define TEXT_SIZE_DEFAULT 20
//滑动自动跑的间隔时间
#define SLIDE_ONE_TIME 30
//按下时间超过此值不算点击操作
#define MAX_TIME_NOT_TO_CLICK 500
//最小大小才写章节到文件
#define MIN_WRITE_CHAPTER_SIZE 20
//获取网页书章节内容重复最大失败次数
#define GET_WEB_REPEAT_TIMES 3


extern QSettings* g_set;
extern map<wstring, wstring> g_mapRegularFilter;
extern bool g_bAndroidForegroundRunning;
extern int g_get_web_repeat_times;

inline bool MKDIR(QString path)
{
	QDir dir;
	return dir.mkpath(path);
}

struct sBookSaveInfo
{
	int chapter = 0;
	int pos = 0;
};

struct sBookInfo
{
	sBookInfo(QString name_in = "", QString path_in = "") :
		name(name_in), path(path_in)
	{}

	auto IsWeb()
	{
		return path.left(4) == "http";
	}
	QString name;
	QString path;
	QString strAuthor;
	QString strUpdateTime;
	QString strChapterHead;
	QString status;
	int maxChapter = 1000;
	bool utf8 = true;
	Qt::CheckState sort = Qt::CheckState::Unchecked;
	//下面chapter和pos必须放一起，后面有地方使用这2个数据来保存到文件
	int chapter = 0;
	int pos = 0;

	void ReadChapterInfo()
	{
		FILE* fp = NULL;
		string strFilePath = BOOK_LIST_SAVE_DIR;
		strFilePath += name.toLocal8Bit().data();
		if (NULL != (fp = fopen(strFilePath.c_str(), "rb+")))
		{
			sBookSaveInfo bookInfo;
			auto len = fread(&bookInfo, 1, sizeof(sBookSaveInfo), fp);
			if (len == sizeof(sBookSaveInfo))
				*(sBookSaveInfo*)&chapter = bookInfo;
			fclose(fp);
		}
		//else
		//{
		//	*(sBookSaveInfo*)&book.chapter = sBookSaveInfo();
		//}
	}

	void SaveChapterInfo()
	{
		QString strFilePath = BOOK_LIST_SAVE_DIR;
		strFilePath += name;
		ofstream fileWrite(strFilePath.toLocal8Bit(), ios::out | ios::binary);
		if (fileWrite)
		{
			fileWrite.write((const char*)&chapter, sizeof(sBookSaveInfo));
			fileWrite.close();
		}
	}

};

struct BookChapterList {
	QString head;
	QString text;
	QString url;
	BookChapterList(QString text_t = "", QString head_t = "", QString url_t = "") :head(head_t), text(text_t), url(url_t)
	{
	}
	auto GetHeadAndText()
	{
		//需要清理text前头和章头相同的重复行
		text.remove(head);
		return head + "\n" + text;
	}
};


extern deque<sBookInfo> m_listBookInfo;
extern std::mutex g_mtxListBookPosChange;

QString getUrlFullPath(QString strUrl, QString strUrlTail);
QString GetListWidgetBookItemString(sBookInfo& book);
string GetWebHeadPropertyContent(string& strText, string str);
void GetWebBookInfo(string& strText, sBookInfo& book);
int BMSearch(const char* strSrc, int lenSrc, const char* strSub, int lenSub);
bool isUTF8(const char* rawtext, size_t rawtextlen = 0x200);
int GetUTF8CharSize(char* rawtext, int rawtextlen);
QByteArray ANSIToUTF8(const char* strSrc);
QByteArray UTF8ToANSI(const char* strSrc);
QString ToUnicode(const char* strSrc, const char* strCharset = "gbk");
int DelSuffixFile(const string rootpath, const string strSuffix, bool& bStop, int level = 1);
string GetCharset(const string& str);
QString& ModifySymbol(QString& str);
QString& DeleteSymbol(QString& str);

int64_t chineseNum2num(const wstring& s);
std::string CurrentDate();
void SaveBookListInfo();
std::string ReadFileToString(const std::string& filename);

#endif // COMMON_H
